<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>2RTK NTRIP server 配置</title>
  <script src="https://cdn.tailwindcss.com"></script>
  <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/lipis/flag-icons@7.0.0/css/flag-icons.min.css">
  <link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;500;700;900&family=Exo+2:wght@300;400;600&display=swap" rel="stylesheet">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@v7.3.0/ol.css">
  <script>
    tailwind.config = {
      theme: {
        extend: {
          colors: {
            primary: '#4DE7FF',
            secondary: '#36CFC9',
            success: '#00F9A6',
            warning: '#FFB74D',
            danger: '#FF5E7D',
            info: '#A0AEC0',
            dark: '#1D2129',
            space: '#0A0F1F',
            stardust: '#1A2138'
          },
          fontFamily: {
            orbitron: ['Orbitron', 'sans-serif'],
            exo: ['Exo 2', 'sans-serif'],
          },
        },
      }
    }
  </script>
  <style type="text/tailwindcss">
    @layer utilities {
      .content-auto {
        content-visibility: auto;
      }
      .signal-bar {
        transition: all 0.3s ease;
        transform-origin: bottom;
        display: inline-flex;
        align-items: flex-end;
        box-shadow: inset 0 -2px 10px rgba(77, 231, 255, 0.3);
      }
      .signal-bar:hover {
        transform: scaleY(1.05);
        box-shadow: 0 0 15px rgba(77, 231, 255, 0.5), inset 0 -2px 4px rgba(0,0,0,0.1);
      }
      .pulse-animation {
        animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
      }
      @keyframes pulse {
        0%, 100% {
          opacity: 1;
        }
        50% {
          opacity: 0.7;
        }
      }
      .fade-in {
        animation: fadeIn 0.5s ease-in-out;
      }
      @keyframes fadeIn {
        from { opacity: 0; transform: translateY(10px); }
        to { opacity: 1; transform: translateY(0); }
      }
      .fixed-height-signal-bars {
        height: 140px;
        display: flex;
        align-items: flex-end;
        flex-wrap: nowrap;
        overflow-x: auto;
      }
      .scrollbar-hide::-webkit-scrollbar {
        height: 6px;
      }
      .scrollbar-hide::-webkit-scrollbar-track {
        background: rgba(77, 231, 255, 0.1);
        border-radius: 3px;
      }
      .scrollbar-hide::-webkit-scrollbar-thumb {
        background: rgba(77, 231, 255, 0.5);
        border-radius: 3px;
      }
      .scrollbar-hide::-webkit-scrollbar-thumb:hover {
        background: rgba(77, 231, 255, 0.8);
      }
      @keyframes loading {
        0% { transform: translateY(0); }
        50% { transform: translateY(-10px); }
        100% { transform: translateY(0); }
      }
      .loading-bar {
        animation: loading 1.5s ease-in-out infinite;
      }
      .loading-bar:nth-child(2) { animation-delay: 0.1s; }
      .loading-bar:nth-child(3) { animation-delay: 0.2s; }
      .loading-bar:nth-child(4) { animation-delay: 0.3s; }
      .loading-bar:nth-child(5) { animation-delay: 0.4s; }
      body {
        background: radial-gradient(ellipse at center, #0a0f1f 0%, #050813 70%);
        color: white;
        font-family: 'Exo 2', sans-serif;
      }
      .space-card {
        background: rgba(10, 20, 40, 0.7);
        backdrop-filter: blur(10px);
        border: 1px solid rgba(77, 231, 255, 0.2);
        box-shadow: 0 0 20px rgba(77, 231, 255, 0.1), 
                    inset 0 0 10px rgba(77, 231, 255, 0.05);
      }
      .glow-border {
        position: relative;
      }
      .glow-border::before {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        height: 3px;
        background: linear-gradient(90deg, #4DE7FF, #00F9A6);
        box-shadow: 0 0 10px rgba(77, 231, 255, 0.7);
        border-radius: 3px 3px 0 0;
        z-index: 1;
      }
      .satellite-glow {
        filter: drop-shadow(0 0 5px rgba(77, 231, 255, 0.7));
      }
      .star {
        position: absolute;
        background: white;
        border-radius: 50%;
        animation: twinkle 4s infinite;
      }
      @keyframes twinkle {
        0%, 100% { opacity: 0.2; }
        50% { opacity: 1; }
      }
      .fi {
        background-size: contain;
        background-position: 50%;
        background-repeat: no-repeat;
        position: relative;
        display: inline-block;
        height: 1.5em;
        line-height: 1.5em;
      }
      .fi:before {
        content: "\00a0";
      }
      .flex.items-center .fi {
        vertical-align: middle;
      }
      #map-container {
        position: relative;
        height: 300px;
        border-radius: 0.5rem;
        overflow: hidden;
        background: rgba(10, 20, 40, 0.5);
        border: 1px solid rgba(77, 231, 255, 0.3);
        margin-top: 1rem;
      }
      .map-placeholder {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        background: linear-gradient(135deg, rgba(10, 20, 40, 0.8), rgba(5, 8, 19, 0.9));
        z-index: 10;
      }
      .map-grid {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background-image: 
          linear-gradient(rgba(77, 231, 255, 0.1) 1px, transparent 1px),
          linear-gradient(90deg, rgba(77, 231, 255, 0.1) 1px, transparent 1px);
        background-size: 20px 20px;
      }
     
      .rtcm-data {
        white-space: normal;
        word-wrap: break-word;
      }
      
      .form-input {
        background-color: rgba(255, 255, 255, 0.1);
        border-color: rgba(77, 231, 255, 0.3);
        color: #A0AEC0; 
        transition: all 0.3s ease;
      }
      .form-input:focus {
        background-color: rgba(255, 255, 255, 0.15);
        border-color: #4DE7FF;
        box-shadow: 0 0 0 3px rgba(77, 231, 255, 0.3);
        outline: none;
      }
      .form-label {
        color: #4DE7FF; 
        margin-bottom: 0.25rem;
        display: block;
      }
     
      .form-placeholder {
        color: rgba(160, 174, 192, 0.6); 
      }
     
      .nav-link {
        font-size: 1.25rem; 
        color: #FF9800; 
        margin-left: 2rem; 
      }
      
      .nav-container {
        justify-content: center;
      }
    }
  </style>
</head>
<body class="min-h-screen flex flex-col">
  <div id="stars" class="fixed inset-0 z-0"></div>
  <header class="space-card sticky top-0 z-50">
    <div class="container mx-auto px-4 py-3 flex flex-wrap items-center">
      <div class="flex items-center space-x-3">
        <i class="fa fa-satellite text-primary text-2xl satellite-glow"></i>
        <h1 class="text-xl md:text-2xl font-bold font-orbitron tracking-wider">2RTK NTRIP server<span class="text-primary"></span>设置</h1>
      </div>
      
      <div class="flex justify-center items-center space-x-4 mt-2 sm:mt-0 nav-container">
        <a href="/" class="text-primary hover:text-white nav-link">状态信息</a>
        <a href="/config" class="text-primary hover:text-white nav-link">运行设置</a>
        <a href="/login" class="text-primary hover:text-white nav-link">登录</a>
      </div>
    </div>
  </header>
  <main class="flex-grow container mx-auto px-4 py-6 relative z-10">
    <div class="max-w-4xl mx-auto mt-10 space-card p-8 rounded shadow">
      <h1 class="text-2xl font-bold mb-6">2RTK NTRIP server 设置</h1>

      <div class="flex justify-end mb-4">
        <button onclick="loadConfig()" class="bg-gray-500 hover:bg-gray-600 text-white px-3 py-1 rounded">
          读取当前配置信息
        </button>
      </div>

      <form method="POST" action="/config" id="configForm" class="space-y-4">
        <div>
          <label class="form-label font-semibold">Mode运行模式:</label>
          <select name="mode" class="form-input w-full rounded" required>
            <option value="none" {{ 'selected' if config.mode == 'none' }}>none (默认)</option>
            <option value="serial" {{ 'selected' if config.mode == 'serial' }}>Serial串口模式</option>
            <option value="relay" {{ 'selected' if config.mode == 'relay' }}>Relay中继模式</option>
          </select>
        </div>

        
        <div class="grid grid-cols-2 gap-4 field-serial">
          <div>
            <label class="form-label font-semibold">Serial port串口名称:</label>
            <input type="text" name="serial_port" value="{{ config.serial_port or ''}}" class="form-input w-full rounded" placeholder="可选">
          </div>
          <div>
            <label class="form-label font-semibold">Baud Rate 串口波特率:</label>
            <input type="number" name="baud_rate" value="{{ config.baud_rate or '' }}" class="form-input w-full rounded" list="baud-rates">
            <datalist id="baud-rates">
              <option value="115200">115200</option>
              <option value="230400">230400</option>
              <option value="460800">460800</option>
              <option value="921600">921600</option>
              <option value="9600">9600</option>
              <option value="9600">57600</option>
            </datalist>
          </div>
        </div>
        <div class="grid grid-cols-2 gap-4 field-caster">
          <div>
            <label class="form-label font-semibold">NTRIP   Caster Addr. 上传地址:</label>
            <input type="text" name="caster_host" value="{{ config.caster_host }}" class="form-input w-full rounded">
          </div>
          <div>
            <label class="form-label font-semibold">NTRIP Caster Port 上传端口:</label>
            <input type="number" name="caster_port" value="{{ config.caster_port }}" class="form-input w-full rounded">
          </div>
        </div>

        <div class="grid grid-cols-2 gap-4 field-caster">
          <div>
            <label class="form-label font-semibold">NTRIP Caster Mount Point上传挂载点:</label>
            <input type="text" name="caster_mountpoint" value="{{ config.caster_mountpoint }}" class="form-input w-full rounded">
          </div>
          <div>
            <label class="form-label font-semibold">NTRIP Caster Upload Password 上传密码:</label>
            <input type="text" name="caster_password" value="{{ config.caster_password }}" class="form-input w-full rounded">
          </div>
        </div>

        
        <div class="grid grid-cols-2 gap-4 field-relay">
          <div>
            <label class="form-label font-semibold">Relay Caster Addr. 中继地址:</label>
            <input type="text" name="relay_host" value="{{ config.relay_host }}" class="form-input w-full rounded">
          </div>
          <div>
            <label class="form-label font-semibold">Relay Caster Port 中继端口:</label>
            <input type="number" name="relay_port" value="{{ config.relay_port }}" class="form-input w-full rounded">
          </div>
        </div>

        <div class="grid grid-cols-2 gap-4 field-relay">
          <div>
            <label class="form-label font-semibold">Relay Caster Mount Point 中继挂载点:</label>
            <input type="text" name="relay_mountpoint" value="{{ config.relay_mountpoint }}" class="form-input w-full rounded">
          </div>
          <div>
            <label class="form-label font-semibold">Relay Caster Username 中继用户名:</label>
            <input type="text" name="relay_user" value="{{ config.relay_user }}" class="form-input w-full rounded">
          </div>
        </div>

        <div class="field-relay">
          <label class="form-label font-semibold">relay Caster Password 中继密码:</label>
            <input type="text" name="relay_password" value="{{ config.relay_password }}" class="form-input w-full rounded">
        </div>

       
        <div class="flex justify-between mt-6">
          <button type="submit" name="restart_program"
                  class="bg-red-600 hover:bg-red-700 text-white px-4 py-2 rounded">
            Apply & Restart 保存重启
          </button>
        </div>
      </form>

      {% if message %}
        <div class="mt-6 p-4 rounded {{ 'bg-green-100 text-green-800' if message_type == 'success' else 'bg-red-100 text-red-800' }}">
          {{ message }}
        </div>
      {% endif %}
    </div>
  </main>
  <footer class="space-card border-t border-gray-700 py-4 mt-8">
    <div class="container mx-auto px-4 text-center text-sm text-info">
      <p class="font-orbitron tracking-wider">2RTK NTRIP server &copy; <span id="year">2025</span></p>
    </div>
  </footer>
  <script>
    function createStars() {
      const starsContainer = document.getElementById('stars');
      const starCount = 150;
      for (let i = 0; i < starCount; i++) {
        const star = document.createElement('div');
        star.classList.add('star');
        const size = Math.random() * 2;
        const posX = Math.random() * 100;
        const posY = Math.random() * 100;
        star.style.width = `${size}px`;
        star.style.height = `${size}px`;
        star.style.left = `${posX}%`;
        star.style.top = `${posY}%`;
        star.style.animationDelay = `${Math.random() * 4}s`;
        starsContainer.appendChild(star);
      }
    }
    document.getElementById('year').textContent = new Date().getFullYear();
    document.addEventListener('DOMContentLoaded', () => {
      createStars();
      updateFormFields(); 
    });

    async function loadConfig() {
      try {
        const res = await fetch('/api/load_config');
        const cfg = await res.json();
        const form = document.getElementById('configForm');

        for (const key in cfg) {
          const input = form.querySelector(`[name="${key.toLowerCase()}"]`);
          if (input) {
            input.value = cfg[key] !== null ? cfg[key] : '';
          }
        }

        
        const mode = cfg.mode;
        document.querySelector('select[name="mode"]').value = mode;
        updateFormFields(mode);

      } catch (err) {
        alert("配置读取失败：" + err.message);
      }
    }

    function updateFormFields(mode = document.querySelector('select[name="mode"]').value) {
     
      const serialFields = document.querySelectorAll('.field-serial');
      serialFields.forEach(el => {
        el.style.display = (mode === 'serial') ? 'block' : 'none';
        el.querySelector('input')?.toggleAttribute('required', false); 
      });

      
      const relayFields = document.querySelectorAll('.field-relay');
      relayFields.forEach(el => {
        el.style.display = (mode === 'relay') ? 'block' : 'none';
        el.querySelector('input')?.toggleAttribute('required', mode === 'relay');
      });

      
      const casterFields = document.querySelectorAll('.field-caster');
      casterFields.forEach(el => {
        const required = (mode !== 'none');
        el.style.display = required ? 'block' : 'none';
        el.querySelector('input')?.toggleAttribute('required', required);
      });
    }

    document.querySelector('select[name="mode"]').addEventListener('change', () => {
      updateFormFields();
    });
  </script>

  <script src="https://cdn.jsdelivr.net/npm/ol@v7.3.0/dist/ol.js"></script>
</body>
</html>